home *** CD-ROM | disk | FTP | other *** search
/ SGI Freeware 1999 November / SGI Freeware 1999 November - Disc 1.iso / dist / fw_Tix.idb / usr / freeware / lib / tix4.1 / ComboBox.tcl.z / ComboBox.tcl
Text File  |  1999-01-26  |  34KB  |  1,534 lines

  1. # tixCombobox --
  2. #
  3. #    A combobox widget is basically a listbox widget with an entry
  4. #    widget.
  5. #
  6. #
  7. # Copyright (c) 1996, Expert Interface Technologies
  8. #
  9. # See the file "license.terms" for information on usage and redistribution
  10. # of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  11.  
  12. tixWidgetClass tixComboBox {
  13.     -classname TixComboBox
  14.     -superclass tixLabelWidget
  15.     -method {
  16.     addhistory align appendhistory flash invoke insert pick popdown
  17.     }
  18.     -flag {
  19.     -anchor -arrowbitmap -browsecmd -command -crossbitmap
  20.     -disablecallback -disabledforeground -dropdown -editable
  21.     -fancy -grab -histlimit -historylimit -history -listcmd
  22.     -listwidth -prunehistory -selection -selectmode -state
  23.     -tickbitmap -validatecmd -value -variable
  24.     }
  25.     -static {
  26.     -dropdown -fancy
  27.     }
  28.     -forcecall {
  29.     -variable -selectmode -state
  30.     }
  31.     -configspec {
  32.     {-arrowbitmap arrowBitmap ArrowBitmap ""}
  33.     {-anchor anchor Anchor w}
  34.     {-browsecmd browseCmd BrowseCmd ""}
  35.         {-command command Command ""}
  36.     {-crossbitmap crossBitmap CrossBitmap ""}
  37.     {-disablecallback disableCallback DisableCallback 0 tixVerifyBoolean}
  38.     {-disabledforeground disabledForeground DisabledForeground #606060}
  39.     {-dropdown dropDown DropDown true tixVerifyBoolean}
  40.     {-editable editable Editable false tixVerifyBoolean}
  41.     {-fancy fancy Fancy false tixVerifyBoolean}
  42.     {-grab grab Grab global}
  43.     {-listcmd listCmd ListCmd ""}
  44.     {-listwidth listWidth ListWidth ""}
  45.     {-historylimit historyLimit HistoryLimit ""}
  46.     {-history history History false tixVerifyBoolean}
  47.     {-prunehistory pruneHistory PruneHistory true tixVerifyBoolean}
  48.     {-selectmode selectMode SelectMode browse}
  49.     {-selection selection Selection ""}
  50.         {-state state State normal}
  51.     {-validatecmd validateCmd ValidateCmd ""}
  52.     {-value value Value ""}
  53.     {-variable variable Variable ""}
  54.     {-tickbitmap tickBitmap TickBitmap ""}
  55.     }
  56.     -alias {
  57.     {-histlimit -historylimit}
  58.     }
  59.     -default {
  60.     {*Entry.relief                sunken}
  61.     {*TixScrolledListBox.scrollbar        auto}
  62.     {*Listbox.exportSelection        false}
  63.     {*Listbox.takeFocus            false}
  64.     {*shell.borderWidth            2}
  65.     {*shell.relief                raised}
  66.     {*shell.cursor                arrow}
  67.     {*Button.anchor                c}
  68.     {*Button.borderWidth            1}
  69.     {*Button.highlightThickness        0}
  70.     {*Button.padX                0}
  71.     {*Button.padY                0}
  72.     {*tick.width                18}
  73.     {*tick.height                18}
  74.     {*cross.width                18}
  75.     {*cross.height                18}
  76.     {*arrow.anchor                c}
  77.     {*arrow.width                15}
  78.     {*arrow.height                18}
  79.     {*Entry.background            #c3c3c3}
  80.     {*Label.font         -Adobe-Helvetica-Bold-R-Normal--*-120-*-*-*-*-*-*}
  81.     }
  82. }
  83.  
  84. # States: normal numbers: for dropdown style
  85. #         d+digit(s)    : for non-dropdown style
  86. #
  87. proc tixComboBox:InitWidgetRec {w} {
  88.     upvar #0 $w data
  89.  
  90.     tixChainMethod $w InitWidgetRec
  91.  
  92.     set data(curIndex)    ""
  93.     set data(varInited)      0
  94.     set data(state)       none
  95.     set data(ignore)      0
  96.  
  97.     if {$data(-history)} {
  98.         set data(-editable) 1
  99.     }
  100.  
  101.     if ![string compare $data(-arrowbitmap) ""] {
  102.     set data(-arrowbitmap) [tix getbitmap cbxarrow]
  103.     }
  104.     if ![string compare $data(-crossbitmap) ""] {
  105.     set data(-crossbitmap) [tix getbitmap cross]
  106.     }
  107.     if ![string compare $data(-tickbitmap) ""] {
  108.     set data(-tickbitmap) [tix getbitmap tick]
  109.     }
  110. }
  111.  
  112. proc tixComboBox:ConstructFramedWidget {w frame} {
  113.     upvar #0 $w data
  114.  
  115.     tixChainMethod $w ConstructFramedWidget $frame
  116.  
  117.     if {$data(-dropdown)} {
  118.     tixComboBox:ConstructEntryFrame $w $frame
  119.     tixComboBox:ConstructListShell $w
  120.     } else {
  121.     set f1 [frame $frame.f1]
  122.     set f2 [frame $frame.f2]
  123.  
  124.     tixComboBox:ConstructEntryFrame $w $f1
  125.     tixComboBox:ConstructListFrame  $w $f2
  126.     pack $f1 -side top -pady 2 -fill x
  127.     pack $f2 -side top -pady 2 -fill both -expand yes
  128.     }
  129. }
  130.  
  131. proc tixComboBox:ConstructEntryFrame {w frame} {
  132.     upvar #0 $w data
  133.  
  134.     # (1) The entry
  135.     #
  136.     set data(w:entry) [entry $frame.entry]
  137.  
  138.     if {!$data(-editable)} {
  139.     set bg [$w cget -bg]
  140.     $data(w:entry) config -bg $bg -state disabled -takefocus 1
  141.     }
  142.  
  143.     # This is used during "config-state"
  144.     #
  145.     set data(entryfg) [$data(w:entry) cget -fg]
  146.  
  147.     # (2) The dropdown button, not necessary when not in dropdown mode
  148.     #
  149.     set data(w:arrow) [button $frame.arrow -bitmap $data(-arrowbitmap)]
  150.     if {!$data(-dropdown)} {
  151.     set xframe [frame $frame.xframe -width 19]
  152.     }
  153.  
  154.     # (3) The fancy tick and cross buttons
  155.     #
  156.     if {$data(-fancy)} {
  157.     if {$data(-editable)} {
  158.            set data(w:cross)  [button $frame.cross -bitmap $data(-crossbitmap)]
  159.        set data(w:tick)   [button $frame.tick  -bitmap $data(-tickbitmap)]
  160.  
  161.        pack $frame.cross -side left -padx 1
  162.        pack $frame.tick  -side left -padx 1
  163.     } else {
  164.        set data(w:tick)   [button $frame.tick  -bitmap $data(-tickbitmap)]
  165.        pack $frame.tick  -side left -padx 1
  166.     }
  167.     }
  168.  
  169.     if {$data(-dropdown)} {
  170.     pack $data(w:arrow) -side right -padx 1
  171.     foreach wid "$data(w:frame) $data(w:label)" {
  172.         tixAddBindTag $wid TixComboWid
  173.         tixSetMegaWidget $wid $w TixComboBox
  174.     }
  175.     } else {
  176.     pack $xframe -side right -padx 1
  177.     }
  178.     pack $frame.entry -side right -fill x -expand yes -padx 1
  179. }
  180.  
  181. proc tixComboBox:ConstructListShell {w} {
  182.     upvar #0 $w data
  183.  
  184.     # Create the shell and the list
  185.     #------------------------------
  186.     set data(w:shell) [menu $w.shell -bd 2 -relief raised -tearoff 0]
  187.     wm overrideredirect $data(w:shell) 1
  188.     wm withdraw $data(w:shell)
  189.  
  190.     set data(w:slistbox) [tixScrolledListBox $data(w:shell).slistbox \
  191.     -anchor $data(-anchor) \
  192.     -options {listbox.selectMode "browse"}]
  193.  
  194.     set data(w:listbox) [$data(w:slistbox) subwidget listbox]
  195.  
  196.     pack $data(w:slistbox) -expand yes -fill both -padx 2 -pady 2
  197. }
  198.  
  199. proc tixComboBox:ConstructListFrame {w frame} {
  200.     upvar #0 $w data
  201.  
  202.     set data(w:slistbox) [tixScrolledListBox $frame.slistbox \
  203.     -anchor $data(-anchor)]
  204.  
  205.     set data(w:listbox) [$data(w:slistbox) subwidget listbox]
  206.  
  207.     pack $data(w:slistbox) -expand yes -fill both
  208. }
  209.  
  210.  
  211. proc tixComboBox:SetBindings {w} {
  212.     upvar #0 $w data
  213.  
  214.     tixChainMethod $w SetBindings
  215.  
  216.     # (1) Fix the bindings for the combobox
  217.     #
  218.     bindtags $w "$w TixComboBox [winfo toplevel $w] all"
  219.  
  220.     # (2) The entry subwidget
  221.     #
  222.     tixSetMegaWidget $data(w:entry) $w TixComboBox
  223.  
  224.     bindtags $data(w:entry) [list $data(w:entry) Entry TixComboEntry\
  225.     TixComboWid [winfo toplevel $data(w:entry)] all]
  226.  
  227.     # (3) The listbox and slistbox
  228.     #
  229.     $data(w:slistbox) config -browsecmd \
  230.     "tixComboBox:LbBrowse  $w"
  231.     $data(w:slistbox) config -command\
  232.     "tixComboBox:LbCommand $w"
  233.     $data(w:listbox) config -takefocus 0
  234.  
  235.     tixAddBindTag $data(w:listbox)  TixComboLb
  236.     tixAddBindTag $data(w:slistbox) TixComboLb
  237.     tixSetMegaWidget $data(w:listbox)  $w TixComboBox
  238.     tixSetMegaWidget $data(w:slistbox) $w TixComboBox
  239.  
  240.     # (4) The buttons
  241.     #
  242.     if {$data(-dropdown)} {
  243.     $data(w:arrow) config -takefocus 0
  244.     tixAddBindTag $data(w:arrow) TixComboArrow
  245.     tixSetMegaWidget $data(w:arrow) $w TixComboBox
  246.  
  247.     bind $data(w:root) <1>                "tixComboBox:RootDown $w"
  248.     bind $data(w:root) <ButtonRelease-1>  "tixComboBox:RootUp   $w"
  249.     }
  250.  
  251.     if {$data(-fancy)} {
  252.     if {$data(-editable)} {
  253.         $data(w:cross) config -command "tixComboBox:CrossBtn $w" \
  254.         -takefocus 0
  255.     }
  256.     $data(w:tick) config -command "tixComboBox:Invoke $w" -takefocus 0
  257.     }
  258.  
  259.     if {$data(-dropdown)} {
  260.     set data(state) 0
  261.     } else {
  262.     set data(state) n0
  263.     }    
  264. }
  265.  
  266. proc tixComboBoxBind {} {
  267.     #----------------------------------------------------------------------
  268.     # The class bindings for the TixComboBox
  269.     #
  270.     tixBind TixComboBox <Escape> {
  271.     if [tixComboBox:EscKey %W] {
  272.         break
  273.     }
  274.     }
  275.     tixBind TixComboBox <Configure> {
  276.     tixWidgetDoWhenIdle tixComboBox:align %W
  277.     }
  278.     # Only the two "linear" detail_fields  are for tabbing (moving) among
  279.     # widgets inside the same toplevel. Other detail_fields are sort
  280.     # of irrelevant
  281.     #
  282.     tixBind TixComboBox <FocusOut>  {
  283.     if {![string compare %d NotifyNonlinear] ||
  284.         ![string compare %d NotifyNonlinearVirtual]} {
  285.  
  286.         if [info exists %W(cancelTab)] {
  287.         unset %W(cancelTab)
  288.         } else {
  289.         if [string compare [set %W(-state)] disabled] {
  290.             if [string compare [set %W(-selection)] [set %W(-value)]] {
  291.             tixComboBox:Invoke %W
  292.             }
  293.         }
  294.         }
  295.     }
  296.     }
  297.     tixBind TixComboBox <FocusIn>  {
  298.     if {[tixStrEq %d NotifyNonlinear] || 
  299.         [tixStrEq %d NotifyNonlinearVirtual]} {
  300.  
  301.         focus [%W subwidget entry]
  302.         [set %W(w:entry)] selection from 0
  303.         [set %W(w:entry)] selection to end
  304.     }
  305.     }
  306.  
  307.     #----------------------------------------------------------------------
  308.     # The class tixBindings for the arrow button widget inside the TixComboBox
  309.     #
  310.  
  311.     tixBind TixComboArrow <1>               {
  312.     tixComboBox:ArrowDown [tixGetMegaWidget %W TixComboBox]
  313.     }
  314.     tixBind TixComboArrow <ButtonRelease-1> {
  315.     tixComboBox:ArrowUp   [tixGetMegaWidget %W TixComboBox]
  316.     }
  317.     tixBind TixComboArrow <Escape>          {
  318.     if [tixComboBox:EscKey [tixGetMegaWidget %W TixComboBox]] {
  319.         break
  320.     }
  321.     }
  322.  
  323.  
  324.     #----------------------------------------------------------------------
  325.     # The class tixBindings for the entry widget inside the TixComboBox
  326.     #
  327.     tixBind TixComboEntry <Up>        {
  328.     tixComboBox:EntDirKey [tixGetMegaWidget %W TixComboBox] up
  329.     }
  330.     tixBind TixComboEntry <Down>    {
  331.     tixComboBox:EntDirKey [tixGetMegaWidget %W TixComboBox] down
  332.     }
  333.     tixBind TixComboEntry <Prior>    {
  334.     tixComboBox:EntDirKey [tixGetMegaWidget %W TixComboBox] pageup
  335.     }
  336.     tixBind TixComboEntry <Next>    {
  337.     tixComboBox:EntDirKey [tixGetMegaWidget %W TixComboBox] pagedown
  338.     }
  339.     tixBind TixComboEntry <Return>    {    
  340.     tixComboBox:EntReturnKey [tixGetMegaWidget %W TixComboBox]
  341.     }
  342.     tixBind TixComboEntry <KeyPress>    {
  343.     tixComboBox:EntKeyPress [tixGetMegaWidget %W TixComboBox]
  344.     }
  345.     tixBind TixComboEntry <Escape>     {
  346.     if [tixComboBox:EscKey [tixGetMegaWidget %W TixComboBox]] {
  347.         break
  348.     }
  349.     }
  350.     tixBind TixComboEntry <Tab>     {
  351.     if {[set [tixGetMegaWidget %W TixComboBox](-state)] != "disabled"} {
  352.         if [tixComboBox:EntTab [tixGetMegaWidget %W TixComboBox]] {
  353.         break
  354.         }
  355.     }
  356.     }
  357.     tixBind TixComboEntry <1>    {
  358.     if {[set [tixGetMegaWidget %W TixComboBox](-state)] != "disabled"} {
  359.         focus %W
  360.     }
  361.     }
  362.     tixBind TixComboEntry <ButtonRelease-2>    {
  363.     tixComboBox:EntKeyPress [tixGetMegaWidget %W TixComboBox]
  364.     }
  365.  
  366.     #----------------------------------------------------------------------
  367.     # The class bindings for the listbox subwidget
  368.     #
  369.  
  370.     tixBind TixComboWid <Escape> {
  371.     if [tixComboBox:EscKey [tixGetMegaWidget %W TixComboBox]] {
  372.         break
  373.     }
  374.     }
  375.  
  376.     #----------------------------------------------------------------------
  377.     # The class bindings for some widgets inside ComboBox
  378.     #
  379.     tixBind TixComboWid <ButtonRelease-1> {
  380.     tixComboBox:WidUp [tixGetMegaWidget %W TixComboBox]
  381.     }
  382.     tixBind TixComboWid <Escape> {
  383.     if [tixComboBox:EscKey [tixGetMegaWidget %W TixComboBox]] {
  384.         break
  385.     }
  386.     }
  387. }
  388.  
  389. #----------------------------------------------------------------------
  390. #              Cooked events
  391. #----------------------------------------------------------------------
  392. proc tixComboBox:ArrowDown {w} {
  393.     upvar #0 $w data
  394.  
  395.     if ![string compare $data(-state) disabled] {
  396.     return
  397.     }
  398.     
  399.     case $data(state) {
  400.     {0} {
  401.         tixComboBox:GoState 1 $w
  402.     }
  403.     {2} {
  404.         tixComboBox:GoState 19 $w
  405.     }
  406.     default {
  407.         tixComboBox:StateError $w
  408.     }
  409.     }
  410. }
  411.  
  412. proc tixComboBox:ArrowUp {w} {
  413.     upvar #0 $w data
  414.     
  415.     case $data(state) {
  416.     {1} {
  417.         tixComboBox:GoState 2 $w
  418.     }
  419.     {19} {
  420.         # data(ignore) was already set in state 19
  421.         tixComboBox:GoState 4 $w
  422.     }
  423.     {5} {
  424.         tixComboBox:GoState 13 $w
  425.     }
  426.     default {
  427.         tixComboBox:StateError $w
  428.     }
  429.     }
  430. }
  431.  
  432. proc tixComboBox:RootDown {w} {
  433.     upvar #0 $w data
  434.     
  435.     case $data(state) {
  436.     {0} {
  437.         # Ignore
  438.     }
  439.     {2} {
  440.         tixComboBox:GoState 3 $w
  441.     }
  442.     default {
  443.         tixComboBox:StateError $w
  444.     }
  445.     }
  446. }
  447.  
  448. proc tixComboBox:RootUp {w} {
  449.     upvar #0 $w data
  450.     
  451.     case $data(state) {
  452.     {1} {
  453.         tixComboBox:GoState 12 $w
  454.     }
  455.     {3} {
  456.         # data(ignore) was already set in state 3
  457.         tixComboBox:GoState 4 $w
  458.     }
  459.     {5} {
  460.         tixComboBox:GoState 7 $w
  461.     }
  462.     default {
  463.         tixComboBox:StateError $w
  464.     }
  465.     }
  466. }
  467.  
  468. proc tixComboBox:WidUp {w} {
  469.     upvar #0 $w data
  470.     
  471.     case $data(state) {
  472.     {1} {
  473.         tixComboBox:GoState 12 $w
  474.     }
  475.     {5} {
  476.         tixComboBox:GoState 13 $w
  477.     }
  478.     }
  479. }
  480.  
  481. proc tixComboBox:LbBrowse {w args} {
  482.     upvar #0 $w data
  483.  
  484.     set event [tixEvent type]
  485.     set x [tixEvent flag x]
  486.     set y [tixEvent flag y]
  487.     set X [tixEvent flag X]
  488.     set Y [tixEvent flag Y]
  489.  
  490.     if ![string compare $data(-state) disabled] {
  491.     return
  492.     }
  493.  
  494.     case $event {
  495.     <1> {
  496.         case $data(state) {
  497.         {2} {
  498.             tixComboBox:GoState 5 $w $x $y $X $Y
  499.         }
  500.         {5} {
  501.             tixComboBox:GoState 5 $w $x $y $X $Y
  502.         }
  503.         {n0} {
  504.             tixComboBox:GoState n6 $w $x $y $X $Y
  505.         }
  506.         default {
  507.             tixComboBox:StateError $w
  508.         }
  509.         }
  510.     }
  511.     <ButtonRelease-1> {
  512.         case $data(state) {
  513.         {5} {
  514.             tixComboBox:GoState 6 $w $x $y $X $Y
  515.         }
  516.         {n6} {
  517.             tixComboBox:GoState n0 $w
  518.         }
  519.         default {
  520.             tixComboBox:StateError $w
  521.         }
  522.         }
  523.     }
  524.     default {
  525.         # Must be a motion event
  526.         case $data(state) {
  527.         {1} {
  528.             tixComboBox:GoState 9 $w $x $y $X $Y
  529.         }
  530.         {5} {
  531.             tixComboBox:GoState 5 $w $x $y $X $Y
  532.         }
  533.         {n6} {
  534.             tixComboBox:GoState n6 $w $x $y $X $Y
  535.         }
  536.         default {
  537.             tixComboBox:StateError $w
  538.         }
  539.         }
  540.     }
  541.     }
  542. }
  543.  
  544. proc tixComboBox:LbCommand {w} {
  545.     upvar #0 $w data
  546.  
  547.     case $data(state) {
  548.     {n0} {
  549.         tixComboBox:GoState n1 $w
  550.     }
  551.     }
  552. }
  553.  
  554. #----------------------------------------------------------------------
  555. #           General keyboard event
  556.  
  557. # returns 1 if the combobox is in some special state and the Escape key
  558. # shouldn't be handled by the toplevel bind tag. As a result, when a combobox
  559. # is popped up in a dialog box, Escape will popdown the combo. If the combo
  560. # is not popped up, Escape will invoke the toplevel bindtag (which can
  561. # pop down the dialog box)
  562. #
  563. proc tixComboBox:EscKey {w} {
  564.     upvar #0 $w data
  565.  
  566.     if ![string compare $data(-state) disabled] {
  567.     return
  568.     }
  569.  
  570.     case $data(state) {
  571.     {0} {
  572.         tixComboBox:GoState 17 $w
  573.     }
  574.     {2} {
  575.         tixComboBox:GoState 16 $w
  576.         return 1
  577.     }
  578.     {n0} {
  579.         tixComboBox:GoState n4 $w
  580.     }
  581.     default {
  582.         # ignore
  583.         return 1
  584.     }
  585.     }
  586.  
  587.     return 0
  588. }
  589.  
  590. #----------------------------------------
  591. # Keyboard events
  592. #----------------------------------------
  593. proc tixComboBox:EntDirKey {w dir} {
  594.     upvar #0 $w data
  595.  
  596.     if ![string compare $data(-state) disabled] {
  597.     return
  598.     }
  599.  
  600.     case $data(state) {
  601.     {0} {
  602.         tixComboBox:GoState 10 $w $dir
  603.     }
  604.     {2} {
  605.         tixComboBox:GoState 11 $w $dir
  606.     }
  607.     {5} {
  608.         # ignore
  609.     }
  610.     {n0} {
  611.         tixComboBox:GoState n3 $w $dir
  612.     }
  613.     }
  614. }
  615.  
  616. proc tixComboBox:EntReturnKey {w} {
  617.     upvar #0 $w data
  618.  
  619.     if ![string compare $data(-state) disabled] {
  620.     return
  621.     }
  622.  
  623.     case $data(state) {
  624.     {0} {
  625.         tixComboBox:GoState 14 $w
  626.     }
  627.     {2} {
  628.         tixComboBox:GoState 15 $w
  629.     }
  630.     {5} {
  631.         # ignore
  632.     }
  633.     {n0} {
  634.         tixComboBox:GoState n1 $w
  635.     }
  636.     }
  637. }
  638.  
  639. # Return 1 == break from the binding == no keyboard focus traversal
  640. proc tixComboBox:EntTab {w} {
  641.     upvar #0 $w data
  642.  
  643.     case $data(state) {
  644.     {0} {
  645.         tixComboBox:GoState 14 $w
  646.         set data(cancelTab) ""
  647.         return 0
  648.     }
  649.     {2} {
  650.         tixComboBox:GoState 15 $w
  651.         set data(cancelTab) ""
  652.         return 0
  653.     }
  654.     {n0} {
  655.         tixComboBox:GoState n1 $w
  656.         set data(cancelTab) ""
  657.         return 0
  658.     }
  659.     default {
  660.         return 1
  661.     }
  662.     }
  663. }
  664.  
  665. proc tixComboBox:EntKeyPress {w} {
  666.     upvar #0 $w data
  667.  
  668.     if {!$data(-editable)} {
  669.     return
  670.     }
  671.     if [tixStrEq $data(-state) disabled] {
  672.     return
  673.     }
  674.  
  675.     case $data(state) {
  676.     {0 2 n0} {
  677.         tixComboBox:ClearListboxSelection $w
  678.         tixComboBox:SetSelection $w [$data(w:entry) get] 0 0
  679.     }
  680.  
  681.     }
  682. }
  683.  
  684. #----------------------------------------------------------------------
  685.  
  686. proc tixComboBox:HandleDirKey {w dir} {
  687.     upvar #0 $w data
  688.  
  689.     if [tixComboBox:CheckListboxSelection $w] {
  690.     case $dir {
  691.         "up" {
  692.         tkListboxUpDown $data(w:listbox) -1
  693.         set data(curIndex) [lindex [$data(w:listbox) curselection] 0]
  694.         tixComboBox:SetSelectionFromListbox $w
  695.         }
  696.         "down" {
  697.         tkListboxUpDown $data(w:listbox)  1
  698.         set data(curIndex) [lindex [$data(w:listbox) curselection] 0]
  699.         tixComboBox:SetSelectionFromListbox $w
  700.         }
  701.         "pageup" {
  702.         $data(w:listbox) yview scroll -1 pages
  703.         }
  704.         "pagedown" {
  705.         $data(w:listbox) yview scroll  1 pages
  706.         }
  707.     }
  708.     } else {
  709.     # There wasn't good selection in the listbox.
  710.     #
  711.     tixComboBox:SetSelectionFromListbox $w
  712.     }
  713. }
  714.  
  715. proc tixComboBox:Invoke {w} {
  716.     upvar #0 $w data
  717.  
  718.     tixComboBox:SetValue $w $data(-selection)
  719.     if ![winfo exists $w] {
  720.     return
  721.     }
  722.  
  723.     if {$data(-history)} {
  724.     tixComboBox:addhistory $w $data(-value)
  725.     set data(curIndex) 0
  726.     }
  727.     $data(w:entry) selection from 0
  728.     $data(w:entry) selection to end
  729.     $data(w:entry) icursor end
  730. }
  731.  
  732. #----------------------------------------------------------------------
  733. #                   MAINTAINING THE -VALUE
  734. #----------------------------------------------------------------------
  735. proc tixComboBox:SetValue {w newValue {noUpdate 0} {updateEnt 1}} {
  736.     upvar #0 $w data
  737.  
  738.     if {$data(-validatecmd) != ""} {
  739.        set data(-value) [tixEvalCmdBinding $w $data(-validatecmd) "" $newValue]
  740.     } else {
  741.     set data(-value) $newValue
  742.     }
  743.  
  744.     if {! $noUpdate} {
  745.     tixVariable:UpdateVariable $w
  746.     }
  747.  
  748.     if {$updateEnt} {
  749.     if {!$data(-editable)} {
  750.         $data(w:entry) delete 0 end
  751.         $data(w:entry) insert 0 $data(-value)
  752.     }
  753.     }
  754.  
  755.     if {!$data(-disablecallback) && $data(-command) != ""} {
  756.     if {![info exists data(varInited)]} {
  757.         set bind(specs) {%V}
  758.         set bind(%V)    $data(-value)
  759.  
  760.         tixEvalCmdBinding $w $data(-command) bind $data(-value)
  761.         if ![winfo exists $w] {
  762.         # The user destroyed the window!
  763.         return
  764.         }
  765.     }
  766.     }
  767.  
  768.     set data(-selection) $data(-value)
  769.     if {$updateEnt} {
  770.     tixSetEntry $data(w:entry) $data(-value)
  771.  
  772.     if {$data(-anchor) == "e"} {
  773.         tixComboBox:EntryAlignEnd $w
  774.     }
  775.     }
  776. }
  777.  
  778. # markSel: should the all the text in the entry be highlighted?
  779. #
  780. proc tixComboBox:SetSelection {w value {markSel 1} {setent 1}} {
  781.     upvar #0 $w data
  782.  
  783.     if {$setent} {
  784.     tixSetEntry $data(w:entry) $value
  785.     }
  786.     set data(-selection) $value
  787.  
  788.     if {$data(-selectmode) == "browse"} {
  789.     if {$markSel} {
  790.         $data(w:entry) selection range 0 end
  791.     }
  792.     if {$data(-browsecmd) != ""} {
  793.         set bind(specs) {%V}
  794.         set bind(%V)    [$data(w:entry) get]
  795.         tixEvalCmdBinding $w $data(-browsecmd) bind [$data(w:entry) get]
  796.     }
  797.     } else {
  798.     tixComboBox:SetValue $w $value 0 0
  799.     }
  800. }
  801.  
  802. proc tixComboBox:ClearListboxSelection {w} {
  803.     upvar #0 $w data
  804.  
  805.     $data(w:listbox) selection clear 0 end
  806. }
  807.  
  808. proc tixComboBox:UpdateListboxSelection {w index} {
  809.     upvar #0 $w data
  810.  
  811.     if {$index != ""} {
  812.     $data(w:listbox) selection set $index
  813.     $data(w:listbox) selection anchor $index
  814.     }
  815. }
  816.  
  817.  
  818. proc tixComboBox:Cancel {w} {
  819.     upvar #0 $w data
  820.  
  821.     tixSetEntry $data(w:entry) $data(-value)
  822.     tixComboBox:SetSelection $w $data(-value)
  823.  
  824.     if {"x[tixComboBox:LbGetSelection $w]" != "x$data(-selection)"} {
  825.     tixComboBox:ClearListboxSelection $w
  826.     }
  827. }
  828.  
  829. proc tixComboBox:flash {w} {
  830.     tixComboBox:BlinkEntry $w
  831. }
  832.  
  833. # Make the entry blink when the user selects a choice
  834. #
  835. proc tixComboBox:BlinkEntry {w} {
  836.     upvar #0 $w data
  837.  
  838.     if {![info exists data(entryBlacken)]} {
  839.     set old_bg [$data(w:entry) cget -bg]
  840.     set old_fg [$data(w:entry) cget -fg]
  841.  
  842.     $data(w:entry) config -fg $old_bg
  843.     $data(w:entry) config -bg $old_fg
  844.  
  845.     set data(entryBlacken) 1
  846.     after 50 tixComboBox:RestoreBlink $w [list $old_bg] [list $old_fg]
  847.     }
  848. }
  849.  
  850. proc tixComboBox:RestoreBlink {w old_bg old_fg} {
  851.     upvar #0 $w data
  852.  
  853.     if {[info exists data(w:entry)] && [winfo exists $data(w:entry)]} {
  854.     $data(w:entry) config -fg $old_fg
  855.     $data(w:entry) config -bg $old_bg
  856.     }
  857.  
  858.     if [info exists data(entryBlacken)] {
  859.     unset data(entryBlacken)
  860.     }
  861. }
  862.  
  863. #----------------------------------------
  864. #  Handle events inside the list box
  865. #----------------------------------------
  866.  
  867. proc tixComboBox:LbIndex {w {flag ""}} {
  868.     upvar #0 $w data
  869.  
  870.     set sel [lindex [$data(w:listbox) curselection] 0]
  871.     if {$sel != ""} {
  872.     return $sel
  873.     } else {
  874.     if {$flag == "emptyOK"} {
  875.         return ""
  876.     } else {
  877.         return 0
  878.     }
  879.     }
  880. }
  881.  
  882. #----------------------------------------------------------------------
  883. #
  884. #            STATE MANIPULATION
  885. #
  886. #----------------------------------------------------------------------
  887. proc tixComboBox:GoState-0 {w} {
  888.     upvar #0 $w data
  889. }
  890.  
  891. proc tixComboBox:GoState-1 {w} {
  892.     upvar #0 $w data
  893.  
  894.     tixComboBox:Popup $w
  895. }
  896.  
  897. proc tixComboBox:GoState-2 {w} {
  898.     upvar #0 $w data
  899.  
  900. }
  901.  
  902. proc tixComboBox:GoState-3 {w} {
  903.     upvar #0 $w data
  904.  
  905.     set data(ignore) 1
  906.     tixComboBox:Popdown $w
  907. }
  908.  
  909. proc tixComboBox:GoState-4 {w} {
  910.     upvar #0 $w data
  911.  
  912.     tixComboBox:Ungrab $w
  913.     if {$data(ignore)} {
  914.     tixComboBox:Cancel $w
  915.     } else {
  916.     tixComboBox:Invoke $w
  917.     }
  918.     tixComboBox:GoState 0 $w
  919. }
  920.  
  921. proc tixComboBox:GoState-5 {w x y X Y} {
  922.     upvar #0 $w data
  923.  
  924.     tixComboBox:LbSelect $w $x $y $X $Y
  925. }
  926.  
  927. proc tixComboBox:GoState-6 {w x y X Y} {
  928.     upvar #0 $w data
  929.  
  930.     tixComboBox:Popdown $w
  931.  
  932.     if [tixWithinWindow $data(w:shell) $X $Y] {
  933.     set data(ignore) 0
  934.     } else {
  935.     set data(ignore) 1
  936.     }
  937.  
  938.     tixComboBox:GoState 4 $w
  939. }
  940.  
  941. proc tixComboBox:GoState-7 {w} {
  942.     upvar #0 $w data
  943.  
  944.     tixComboBox:Popdown $w
  945.     set data(ignore) 1
  946.     catch {
  947.     global tkPriv
  948.     if {$tkPriv(afterId) != ""} {
  949.         tkCancelRepeat
  950.     }
  951.     }
  952.  
  953.     set data(ignore) 1
  954.     tixComboBox:GoState 4 $w
  955. }
  956.  
  957. proc tixComboBox:GoState-9 {w x y X Y} {
  958.     upvar #0 $w data
  959.  
  960.     catch {
  961.     tkButtonUp $data(w:arrow)
  962.     }
  963.     tixComboBox:GoState 5 $w $x $y $X $Y
  964. }
  965.  
  966. proc tixComboBox:GoState-10 {w dir} {
  967.     upvar #0 $w data
  968.  
  969.     tixComboBox:Popup $w
  970.     if {![tixComboBox:CheckListboxSelection $w]} {
  971.     # There wasn't good selection in the listbox.
  972.     #
  973.     tixComboBox:SetSelectionFromListbox $w
  974.     }
  975.  
  976.     tixComboBox:GoState 2 $w
  977. }
  978.  
  979. proc tixComboBox:GoState-11 {w dir} {
  980.     upvar #0 $w data
  981.  
  982.     tixComboBox:HandleDirKey $w $dir
  983.  
  984.     tixComboBox:GoState 2 $w
  985. }
  986.  
  987. proc tixComboBox:GoState-12 {w} {
  988.     upvar #0 $w data
  989.  
  990.     catch {
  991.     tkButtonUp $data(w:arrow)
  992.     }
  993.  
  994.     tixComboBox:GoState 2 $w
  995. }
  996.  
  997. proc tixComboBox:GoState-13 {w} {
  998.     upvar #0 $w data
  999.  
  1000.     catch {
  1001.     global tkPriv
  1002.     if {$tkPriv(afterId) != ""} {
  1003.         tkCancelRepeat
  1004.     }
  1005.     }
  1006.     tixComboBox:GoState 2 $w
  1007. }
  1008.  
  1009. proc tixComboBox:GoState-14 {w} {
  1010.     upvar #0 $w data
  1011.  
  1012.     tixComboBox:Invoke $w
  1013.     tixComboBox:GoState 0 $w
  1014. }
  1015.  
  1016. proc tixComboBox:GoState-15 {w} {
  1017.     upvar #0 $w data
  1018.  
  1019.     tixComboBox:Popdown $w
  1020.     set data(ignore) 0
  1021.     tixComboBox:GoState 4 $w
  1022. }
  1023.  
  1024. proc tixComboBox:GoState-16 {w} {
  1025.     upvar #0 $w data
  1026.  
  1027.     tixComboBox:Popdown $w
  1028.     tixComboBox:Cancel $w
  1029.     set data(ignore) 1
  1030.     tixComboBox:GoState 4 $w
  1031. }
  1032.  
  1033. proc tixComboBox:GoState-17 {w} {
  1034.     upvar #0 $w data
  1035.  
  1036.     tixComboBox:Cancel $w
  1037.     tixComboBox:GoState 0 $w
  1038. }
  1039.  
  1040. proc tixComboBox:GoState-19 {w} {
  1041.     upvar #0 $w data
  1042.  
  1043.     if {"x$data(-selection)" != "x$data(-value)"} {
  1044.     set data(ignore) 0
  1045.     } else {
  1046.     set data(ignore) 1
  1047.     }
  1048.     tixComboBox:Popdown $w
  1049. }
  1050.  
  1051. #----------------------------------------------------------------------
  1052. #                      Non-dropdown states
  1053. #----------------------------------------------------------------------
  1054. proc tixComboBox:GoState-n0 {w} {
  1055.     upvar #0 $w data
  1056. }
  1057.  
  1058. proc tixComboBox:GoState-n1 {w} {
  1059.     upvar #0 $w data
  1060.  
  1061.     tixComboBox:Invoke $w
  1062.     tixComboBox:GoState n0 $w
  1063. }
  1064.  
  1065. proc tixComboBox:GoState-n3 {w dir} {
  1066.     upvar #0 $w data
  1067.  
  1068.     tixComboBox:HandleDirKey $w $dir
  1069.     tixComboBox:GoState n0 $w
  1070. }
  1071.  
  1072. proc tixComboBox:GoState-n4 {w} {
  1073.     upvar #0 $w data
  1074.  
  1075.     tixComboBox:Cancel $w
  1076.     tixComboBox:GoState n0 $w
  1077. }
  1078.  
  1079. proc tixComboBox:GoState-n6 {w x y X Y} {
  1080.     upvar #0 $w data
  1081.  
  1082.     tixComboBox:LbSelect $w $x $y $X $Y
  1083. }
  1084.  
  1085. #----------------------------------------------------------------------
  1086. #                      General State Manipulation
  1087. #----------------------------------------------------------------------
  1088. proc tixComboBox:GoState {s w args} {
  1089.     upvar #0 $w data
  1090.  
  1091.     tixComboBox:SetState $w $s
  1092.     eval tixComboBox:GoState-$s $w $args
  1093. }
  1094.  
  1095. proc tixComboBox:SetState {w s} {
  1096.     upvar #0 $w data
  1097.  
  1098. #    catch {puts [info level -2]}
  1099. #    puts "setting state $data(state) --> $s"
  1100.     set data(state) $s
  1101. }
  1102.  
  1103. proc tixComboBox:StateError {w} {
  1104.     upvar #0 $w data
  1105.  
  1106. #    error "wrong state $data(state)"
  1107. }
  1108.  
  1109. #----------------------------------------------------------------------
  1110. #                      Listbox handling
  1111. #----------------------------------------------------------------------
  1112.  
  1113. # Set a selection if there isn't one. Returns true if there was already
  1114. # a good selection inside the listbox
  1115. #
  1116. proc tixComboBox:CheckListboxSelection {w} {
  1117.     upvar #0 $w data
  1118.  
  1119.     if {[$data(w:listbox) curselection] == ""} {
  1120.     if {$data(curIndex) == ""} {
  1121.         set data(curIndex) 0
  1122.     }
  1123.  
  1124.     $data(w:listbox) activate $data(curIndex)
  1125.     $data(w:listbox) selection clear 0 end
  1126.     $data(w:listbox) selection set $data(curIndex)
  1127.     $data(w:listbox) see $data(curIndex)
  1128.     return 0
  1129.     } else {
  1130.     return 1
  1131.     }
  1132. }
  1133.  
  1134. proc tixComboBox:SetSelectionFromListbox {w} {
  1135.     upvar #0 $w data
  1136.  
  1137.     set string [$data(w:listbox) get $data(curIndex)] 
  1138.     tixComboBox:SetSelection $w $string
  1139.     tixComboBox:UpdateListboxSelection $w $data(curIndex)
  1140. }
  1141.  
  1142. proc tixComboBox:LbGetSelection {w} {
  1143.     upvar #0 $w data
  1144.     set index [tixComboBox:LbIndex $w emptyOK]
  1145.  
  1146.     if {$index >=0} {
  1147.     return [$data(w:listbox) get $index]
  1148.     } else {
  1149.     return ""
  1150.     }
  1151. }
  1152.  
  1153. proc tixComboBox:LbSelect {w x y X Y} {
  1154.     upvar #0 $w data
  1155.  
  1156.     set index [tixComboBox:LbIndex $w emptyOK]
  1157.     if {$index == ""} {
  1158.     set index [$data(w:listbox) nearest $y]
  1159.     }
  1160.  
  1161.     if {$index >= 0} {
  1162.     if {"x[focus -lastfor $data(w:entry)]" != "x$data(w:entry)" &&
  1163.         "x[focus -lastfor $data(w:entry)]" != "x$data(w:listbox)"} {
  1164.         focus $data(w:entry)
  1165.     }
  1166.  
  1167.     set string [$data(w:listbox) get $index] 
  1168.     tixComboBox:SetSelection $w $string
  1169.  
  1170.     tixComboBox:UpdateListboxSelection $w $index
  1171.     }
  1172. }
  1173.  
  1174. #----------------------------------------------------------------------
  1175. # Internal commands
  1176. #----------------------------------------------------------------------
  1177. proc tixComboBox:CrossBtn {w} {
  1178.     upvar #0 $w data
  1179.  
  1180.     $data(w:entry) delete 0 end
  1181.     tixComboBox:ClearListboxSelection $w
  1182.     tixComboBox:SetSelection $w ""
  1183. }
  1184.  
  1185. #--------------------------------------------------
  1186. #        Popping up list shell
  1187. #--------------------------------------------------
  1188.  
  1189. # Popup the listbox and grab
  1190. #
  1191. #
  1192. proc tixComboBox:Popup {w} {
  1193.     upvar #0 $w data
  1194.  
  1195.     if {![winfo ismapped $data(w:root)]} {
  1196.     return
  1197.     }
  1198.  
  1199.     #---------------------------------------------------------------------
  1200.     #                 Pop up
  1201.     #
  1202.     if {$data(-listcmd) != ""} {
  1203.     # This option allows the user to fill in the listbox on demand
  1204.     #
  1205.     tixEvalCmdBinding $w $data(-listcmd)
  1206.     }
  1207.  
  1208.     # calculate the size
  1209.     set  y [winfo rooty $data(w:entry)]
  1210.     incr y [winfo height $data(w:entry)]
  1211.     incr y 3
  1212.  
  1213.     set bd [$data(w:shell) cget -bd]
  1214. #   incr bd [$data(w:shell) cget -highlightthickness]
  1215.     set height [expr [winfo reqheight $data(w:slistbox)] + 2*$bd]
  1216.  
  1217.     set x1 [winfo rootx $data(w:entry)]
  1218.     if {$data(-listwidth) == ""} {
  1219.     if [winfo ismapped $data(w:arrow)] {
  1220.         set x2  [winfo rootx $data(w:arrow)]
  1221.         if {$x2 >= $x1} {
  1222.         incr x2 [winfo width $data(w:arrow)]
  1223.         set width  [expr "$x2 - $x1"]
  1224.         } else {
  1225.         set width  [winfo width $data(w:entry)]
  1226.         set x2 [expr $x1 + $width]
  1227.         }
  1228.     } else {
  1229.         set width  [winfo width $data(w:entry)]
  1230.         set x2 [expr $x1 + $width]
  1231.     }
  1232.     } else {
  1233.     set width $data(-listwidth)
  1234.     set x2 [expr $x1 + $width]
  1235.     }
  1236.  
  1237.     set reqwidth [winfo reqwidth $data(w:shell)]
  1238.     if {$reqwidth < $width} {
  1239.     set reqwidth $width
  1240.     } else {
  1241.     if {$reqwidth > [expr $width *3]} {
  1242.         set reqwidth [expr $width *3]
  1243.     }
  1244.     if {$reqwidth > [winfo vrootwidth .]} {
  1245.         set reqwidth [winfo vrootwidth .]
  1246.     }
  1247.     }
  1248.     set width $reqwidth
  1249.  
  1250.  
  1251.     # If the listbox is too far right, pull it back to the left
  1252.     #
  1253.     set scrwidth [winfo vrootwidth .]
  1254.     if {$x2 > $scrwidth} {
  1255.     set x1 [expr $scrwidth - $width]
  1256.     }
  1257.  
  1258.     # If the listbox is too far left, pull it back to the right
  1259.     #
  1260.     if {$x1 < 0} {
  1261.     set x1 0
  1262.     }
  1263.  
  1264.     # If the listbox is below bottom of screen, put it upwards
  1265.     #
  1266.     set scrheight [winfo vrootheight .]
  1267.     set bottom [expr $y+$height]
  1268.     if {$bottom > $scrheight} {
  1269.     set y [expr $y-$height-[winfo height $data(w:entry)]-5]
  1270.     }
  1271.  
  1272.     # OK , popup the shell
  1273.     #
  1274.     global tcl_platform
  1275.  
  1276.     wm geometry $data(w:shell) $reqwidth\x$height+$x1+$y
  1277.     if {$tcl_platform(platform) == "windows"} {
  1278.     update
  1279.     }
  1280.     wm deiconify $data(w:shell)
  1281.     if {$tcl_platform(platform) == "windows"} {
  1282.     update
  1283.     }
  1284.     raise $data(w:shell)
  1285.     focus $data(w:entry)
  1286.     set data(popped) 1
  1287.  
  1288.     tixComboBox:Grab $w
  1289. }
  1290.  
  1291. proc tixComboBox:SetCursor {w cursor} {
  1292.     upvar #0 $w data
  1293.  
  1294.     $w config -cursor $cursor
  1295. }
  1296.  
  1297. proc tixComboBox:Popdown {w} {
  1298.     upvar #0 $w data
  1299.  
  1300.     wm withdraw $data(w:shell)
  1301.     tixComboBox:SetCursor $w ""
  1302. }
  1303.  
  1304. # Grab the server so that user cannot move the windows around
  1305. proc tixComboBox:Grab {w} {
  1306.     upvar #0 $w data
  1307.  
  1308.     tixComboBox:SetCursor $w arrow
  1309.     catch {
  1310.     # We catch here because grab may fail under a lot of circumstances
  1311.     # Just don't want to break the code ...
  1312.     case $data(-grab) {
  1313.         global {
  1314.         tixPushGrab -global $data(w:root)
  1315.         }
  1316.         local {
  1317.         tixPushGrab $data(w:root)
  1318.         }
  1319.     }
  1320.     }
  1321. }
  1322.  
  1323. proc tixComboBox:Ungrab {w} {
  1324.     upvar #0 $w data
  1325.  
  1326.     case $data(-grab) {
  1327.     global {
  1328.         tixPopGrab
  1329.     }
  1330.     local {
  1331.         tixPopGrab
  1332.     }
  1333.     }
  1334. }
  1335.  
  1336. #----------------------------------------------------------------------
  1337. #         Alignment
  1338. #----------------------------------------------------------------------
  1339. # The following two routines can emulate a "right align mode" for the
  1340. # entry in the combo box.
  1341.  
  1342. proc tixComboBox:EntryAlignEnd {w} {
  1343.     upvar #0 $w data
  1344.     $data(w:entry) xview end
  1345. }
  1346.  
  1347.  
  1348. proc tixComboBox:Destructor {w} {
  1349.     upvar #0 $w data
  1350.  
  1351.     tixUnsetMegaWidget $data(w:entry)
  1352.     tixVariable:DeleteVariable $w
  1353.  
  1354.     # Chain this to the superclass
  1355.     #
  1356.     tixChainMethod $w Destructor
  1357. }
  1358.  
  1359.  
  1360. #----------------------------------------------------------------------
  1361. #                           CONFIG OPTIONS
  1362. #----------------------------------------------------------------------
  1363.  
  1364. proc tixComboBox:config-state {w value} {
  1365.     upvar #0 $w data
  1366.     catch {if {"x[$data(w:arrow) cget -state]" == "x$value"} {
  1367.     set a 1
  1368.     }}
  1369.     if [info exists a] {
  1370.     return
  1371.     }
  1372.  
  1373.     catch {$data(w:arrow) config -state $value}
  1374.     catch {$data(w:tick)  config -state $value}
  1375.     catch {$data(w:cross) config -state $value}
  1376.     catch {$data(w:slistbox) config -state $value}
  1377.  
  1378.     if ![string compare $value normal] {
  1379.     set fg [$data(w:arrow) cget -fg]
  1380.     set entryFg $data(entryfg)
  1381.     } else {
  1382.     set fg [$data(w:arrow) cget -disabledforeground]
  1383.     set entryFg $data(-disabledforeground) 
  1384.     }
  1385.     if [string compare $fg ""] {
  1386.     $data(w:label) config -fg $fg
  1387.     $data(w:listbox) config -fg $fg -selectforeground $fg
  1388.     }
  1389.     $data(w:entry) config -fg $entryFg -selectforeground $entryFg
  1390.  
  1391.     if ![string compare $value normal] {
  1392.     if {$data(-editable)} {
  1393.         $data(w:entry) config -state normal
  1394.     }
  1395.         $data(w:entry) config -takefocus 1
  1396.     } else {
  1397.     if {$data(-editable)} {
  1398.        $data(w:entry) config -state disabled
  1399.         }
  1400.         $data(w:entry) config -takefocus 0
  1401.     }
  1402. }
  1403.  
  1404. proc tixComboBox:config-value {w value} {
  1405.     upvar #0 $w data
  1406.  
  1407.     tixComboBox:SetValue $w $value
  1408.  
  1409.     set data(-selection) $value
  1410.  
  1411.     if {"x[tixComboBox:LbGetSelection $w]" != "x$value"} {
  1412.     tixComboBox:ClearListboxSelection $w
  1413.     }
  1414. }
  1415.  
  1416. proc tixComboBox:config-selection {w value} {
  1417.     upvar #0 $w data
  1418.  
  1419.     tixComboBox:SetSelection $w $value
  1420.  
  1421.     if {"x[tixComboBox:LbGetSelection $w]" != "x$value"} {
  1422.     tixComboBox:ClearListboxSelection $w
  1423.     }
  1424. }
  1425.  
  1426. proc tixComboBox:config-variable {w arg} {
  1427.     upvar #0 $w data
  1428.  
  1429.     if [tixVariable:ConfigVariable $w $arg] {
  1430.        # The value of data(-value) is changed if tixVariable:ConfigVariable 
  1431.        # returns true
  1432.        set data(-selection) $data(-value)
  1433.        tixComboBox:SetValue $w $data(-value) 1
  1434.     }
  1435.     catch {
  1436.     unset data(varInited)
  1437.     }
  1438.     set data(-variable) $arg
  1439. }
  1440.  
  1441.  
  1442. #----------------------------------------------------------------------
  1443. #                     WIDGET COMMANDS
  1444. #----------------------------------------------------------------------
  1445. proc tixComboBox:align {w args} {
  1446.     upvar #0 $w data
  1447.  
  1448.     if {$data(-anchor) == "e"} {
  1449.     tixComboBox:EntryAlignEnd $w
  1450.     }
  1451. }
  1452.  
  1453. proc tixComboBox:addhistory {w value} {
  1454.     upvar #0 $w data
  1455.  
  1456.     tixComboBox:insert $w 0 $value
  1457.     $data(w:listbox) selection clear 0 end
  1458.  
  1459.     if {$data(-prunehistory)} {
  1460.     # Prune from the end
  1461.     # 
  1462.     set max [$data(w:listbox) size]
  1463.     if {$max <= 1} {
  1464.         return
  1465.     }
  1466.     for {set i [expr $max -1]} {$i >= 1} {incr i -1} {
  1467.         if {"x[$data(w:listbox) get $i]" == "x$value"} {
  1468.         $data(w:listbox) delete $i
  1469.         break
  1470.         }
  1471.     }
  1472.     }
  1473. }
  1474.  
  1475. proc tixComboBox:appendhistory {w value} {
  1476.     upvar #0 $w data
  1477.  
  1478.     tixComboBox:insert $w end $value
  1479.     $data(w:listbox) selection clear 0 end
  1480.  
  1481.     if {$data(-prunehistory)} {
  1482.     # Prune from the end
  1483.     # 
  1484.     set max [$data(w:listbox) size]
  1485.     if {$max <= 1} {
  1486.         return
  1487.     }
  1488.     for {set i [expr $max -2]} {$i >= 0} {incr i -1} {
  1489.         if {"x[$data(w:listbox) get $i]" == "x$value"} {
  1490.         $data(w:listbox) delete $i
  1491.         break
  1492.         }
  1493.     }
  1494.     }
  1495. }
  1496.  
  1497. proc tixComboBox:insert {w index newitem} {
  1498.     upvar #0 $w data
  1499.  
  1500.     $data(w:listbox) insert $index $newitem
  1501.  
  1502.     if {$data(-history) && $data(-historylimit) != ""} {
  1503.     if {"x[$data(w:listbox) size]"  == "x$data(-historylimit)"} {
  1504.         $data(w:listbox) delete 0
  1505.     }
  1506.     }
  1507. }
  1508.  
  1509. proc tixComboBox:pick {w index} {
  1510.     upvar #0 $w data
  1511.  
  1512.     $data(w:listbox) activate $index
  1513.     $data(w:listbox) selection clear 0 end
  1514.     $data(w:listbox) selection set active
  1515.     $data(w:listbox) see active
  1516.     set text [$data(w:listbox) get $index]
  1517.  
  1518.     tixComboBox:SetValue $w $text
  1519.  
  1520.     set data(curIndex) $index
  1521. }
  1522.  
  1523. proc tixComboBox:invoke {w} {
  1524.     tixComboBox:Invoke $w
  1525. }
  1526.  
  1527. proc tixComboBox:popdown {w} {
  1528.     upvar #0 $w data
  1529.  
  1530.     if {$data(-dropdown)} {
  1531.     tixComboBox:Popdown $w
  1532.     }
  1533. }
  1534.